#include <iostream>
#include <unistd.h>

//僵尸进程
//先说子进程退出的流程，
//流程1、子进程正常或异常退出，大部分资源释放，留下一个zombie的结构体，包含进程id等信息
//流程2、父进程调用wait或者waitpid，调用即释放该子进程的zombie结构体，此时子进程才完全退出
//僵尸进程产生的原因就是上述流程2的缺失，导致子进程没有完全退出，浪费占用pid
//关于本案例复现了僵尸进程的产生
//但好像子进程退出后，父进程也立即退出了
//建议在终端运行，因为父进程退出后，编辑器不会继续打印子进程的信息
int main(){
    std::cout<< "process_zombie.cpp" << std::endl;

    pid_t childPid;
    childPid = fork();
    if(childPid < 0){
        std::cout<< "fork失败" << std::endl;
        exit(1);
    }else if(childPid == 0){
        //child
        printf("im child, getpid()=%d\n", getpid());
        sleep(2);
        return 0;
    }else{
        printf("im father, getpid()=%d\n", getpid());
        sleep(6);
        printf("im father, getpid()=%d after sleep\n", getpid());
        //father
        system("ps -o pid,ppid,state,tty,command | grep zombie");
    }

    return 0;
}

//运行结果：
// im father, getpid()=47630
// im child, getpid()=47631
// im second child, getpid()=47632
// im father, getpid()=47630 after sleep
// 47630  9233 S+   ttys005  ./process_zombie
// 47631 47630 Z+   ttys005  (process_zombie)
// 47632 47630 S+   ttys005  ./process_zombie
// 47716 47630 S+   ttys005  sh -c ps -o pid,ppid,state,tty,command | grep zombie
// 47718 47716 R+   ttys005  grep zombie
// im second child, getpid()=47632 after sleep